<?php
use frontend\modules\yii2\widgets\layouts\markdown\Markdown;
/* @var $this \yii\web\View */
$this->title = 'View组件的学习和使用-Components组件';
$this->registerMetaTag([
    'name' => 'keywords',
    'content' => 'yii,yii2,框架,应用组件,Components,使用,教程,view'
]);
$this->registerMetaTag([
    'name' => 'description',
    'content' => 'View是视图的意思，是MVC开发模式的重要组成部分。'
]);

$html = [
    "概述" => <<<HTML
# View组件的使用
View组件是视图的重要组成部分，它提供了一系列的功能供视图使用。您可以在生命主体的配置文件中进行全局的View组件配置，也可以在单独的视图中调用View组件的方法实现局部修改。

HTML,
    "config" => <<<HTML
## 配置举例 id=config
View组件的全局配置举例如下：
```php
[
    'components' => [
        'view' => [            
            'metaTags' => [
                '<meta name="author" content="lvzmen">'
            ],
            'theme' => 'app\\themes\MyTheme',
            'renderers' => [
                // you may add Smarty or Twig renderer here
            ]
        ]
    ],
]
```

HTML,
    "metaTags" => <<<HTML
## 元数据（meta） id=meta
元数据（Metadata）通常用于指定网页的描述、关键词、文件的最后修改时间、作者等信息，它不会显示在客户端，但是会被浏览器解析。如果你学过搜索引擎优化，那就会知道正确配置每个网页的元数据是搜索引擎优化的必要内容。在Yii中主要提供两种元数据添加方法：
- 所有页面都一样的元数据（如：作者、网页编码），可以在定义组件的时候配置：
```php
[
    'components' => [
        'view' => [            
            'metaTags' => [
                '<meta name="author" content="lvzmen">',
                '<meta charset="utf-8">'
            ],
        ]
    ],
]
```
上述配置可以应用到所有页面，是定义全局元数据的首选方式；

- 每个页面都不同的元数据（如：关键字、描述），可以在视图页面中调用view组件来配置：
```php
/* @var \$this \yii\web\View */
\$this->registerMetaTag([
    'name' => 'keywords',
    'content' => 'yii,yii2,框架,应用组件,Components,使用,教程,view'
]);
\$this->registerMetaTag([
    'name' => 'description',
    'content' => 'View是视图的意思，是MVC开发模式的重要组成部分。'
]);
```
每个视图默认提供了`\$this`变量，是view组件的实例，因此可以直接使用`\$this`变量来访问view组件提供的各种功能（如：引入js、css等文件）。

HTML,
    "cssFiles" => <<<HTML
## 样式（CSS） id=css
CSS层叠样式表的功能就不多说了，Yii同样提供两种注册方式，全局和局部：
- 全局注册法
```php
[
    'components' => [
        'view' => [
            'cssFiles' => [
                '<link href="vendor/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">',
                '<link href="vendor/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">'
            ]
        ]
    ],
]
```
- 局部注册法  
在视图文件中的任何位置添加如下内容： 
```php
/* @var \$this \yii\web\View */
\$this->registerCssFile("vendor/font-awesome@4.7.0/css/font-awesome.min.css");
\$this->registerCssFile("vendor/bootstrap@3.3.7/dist/css/bootstrap.min.css");
```

上述是专门添加Css文件的途径，对于内嵌式样式，可以使用如下方法：
```php
\$style = <<<CSS
* {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
CSS;

\$this->registerCss(\$style);
```
HTML,
    "js" => <<<HTML
## Javascript id=js
不同与meta和css，js通常有依赖关系（如：yii.js依赖于jquery.js），因此前后顺序很重要。出于这个原因，View组件在提供注册js功能时可以指定注册的位置和依赖关系。
### 位置 id=location
由于js的特殊性，js代码块和js文件可以放置的位置如下：

| 位置 | 值 | 说明 | js代码块 | Js文件 |
|-----|--------------|--------|--------|
| POS_HEAD | 1 |页面head头部中| ✓ | ✓ |
| POS_BEGIN | 2 |页面body开始的位置| ✓ | ✓ |
| POS_END | 3 |页面body结束的位置| ✓ | ✓ |
| POS_READY | 4 |页面body结束的位置| ✓ | ㄨ |
| POS_LOAD | 5 |页面body结束的位置| ✓ | ㄨ |

下面举例说明上述5个位置有什么不同：
```php
[
    'components' => [
        'view' => [            
            'jsFiles' => [
                \yii\web\View::POS_HEAD => [
                    '<script src="vendor/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.js"></script>'
                ],
                \yii\web\View::POS_BEGIN => [
                    '<script src="vendor/sweetalert/2.1.2/sweetalert.min.js"></script>'
                ],
                \yii\web\View::POS_END => [
                    '<script src="vendor/jquery-validate/1.19.3/additional-methods.js"></script>'
                ]
            ],
            'js' => [
                \yii\web\View::POS_READY => [
                    'console.info("POS_READY");'
                ],
                \yii\web\View::POS_LOAD => [
                    'console.info("POS_LOAD");'
                ]
            ]
        ]
    ],
]
```
上述的配置对应的结果如下：
```html
<!doctype html>
<html lang='zh-CN'>
    <head>
        ... ...
        <!--POS_HEAD-->
        <script src="vendor/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.js"></script>
    </head>
    <body>
        <!--POS_BEGIN-->
        <script src="vendor/sweetalert/2.1.2/sweetalert.min.js"></script>
        ...
        ...
        ...
        <!--POS_END-->
        <script src="vendor/jquery-validate/1.19.3/additional-methods.js"></script>
        <!--POS_READY-->
        <script>
            jQuery(function ($) {
                console.info("POS_READY");
            });
        </script>
        <!--POS_LOAD-->
        <script>
            jQuery(window).on('load', function () {
                console.info("POS_LOAD");
            });
        </script>
    </body>
</html>
```

### 局部配置 id=page
上面描述的是全局配置法，适合引入所有页面都需要使用的js，对于页面定制的js可以考虑如下方法引入：
```php
/* @var \$this \yii\web\View */
\$this->registerJsFile("vendor/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.js", [
    "position" => \yii\web\View::POS_HEAD
]);
\$this->registerJsFile("vendor/sweetalert/2.1.2/sweetalert.min.js", [
    "position" => \yii\web\View::POS_BEGIN
]);
\$this->registerJsFile("vendor/jquery-validate/1.19.3/additional-methods.js", [
    "position" => \yii\web\View::POS_END
]);
\$this->registerJs('console.info("POS_READY");',  \yii\web\View::POS_READY);
\$this->registerJs('console.info("POS_LOAD");',  \yii\web\View::POS_LOAD);
```
> 注意：registerJs()的第二个参数不再是数组。

HTML,
    "依赖关系" => <<<HTML
### 依赖关系 id=dependency
js有严格的依赖关系，但是view组件的`registerJsFile()`方法才提供依赖关系设置，使用方法如下：
```php
/* @var \$this \yii\web\View */
// 使用依赖
\$this->registerJsFile("vendor/sweetalert/2.1.2/sweetalert.min.js", [
    "position" => \yii\web\View::POS_END,
    "depends" => [
        '\yii\web\YiiAsset'
    ]
]);
// 不使用依赖
\$this->registerJsFile("vendor/jquery-validate/1.19.3/additional-methods.js", [
    "position" => \yii\web\View::POS_END,
]);
```
上面一个js使用了依赖，另一个不使用依赖，我们看一下效果：
```html
<!doctype html>
<html lang='zh-CN'>
    <head>
    </head>
    <body>
        ... ...
        <!--POS_END-->
        <!--由于jquery-validat不依赖任何js，因此放到第一个加载-->
        <script src="vendor/jquery-validate/1.19.3/additional-methods.js"></script>
        <!--下面这两个是\yii\web\YiiAsset的内容-->
        <script src="/assets/d1d353cb/jquery.js"></script>
        <script src="/assets/a29de2b0/yii.js"></script>
        <!--由于sweetalert.min.js依赖\yii\web\YiiAsset，因此放到它后面加载-->
        <script src="/vendor/sweetalert/2.1.2/sweetalert.min.js"></script>
    </body>
</html>
```
HTML,
    "title" => <<<HTML
## 标题（Title） id=title
每个页面的标题都不一样，标题也是SEO的重要检索目标，不重视标题是搜索排名差的常见原因，`View`组件提供了一个非常方便的方式设置标题，如下：
```php
/* @var \$this \yii\web\View */
\$this->title = 'View组件的学习和使用-Components组件';
```
HTML,
    "" => <<<HTML

HTML,
];


//$this->registerJsFile("vendor/sweetalert/2.1.2/sweetalert.min.js", [
//    "position" => \yii\web\View::POS_END,
//    "depends" => [
//        '\yii\web\YiiAsset'
//    ]
//]);
//$this->registerJsFile("vendor/jquery-validate/1.19.3/additional-methods.js", [
//    "position" => \yii\web\View::POS_END,
//]);
//$this->registerJs('console.info("POS_LOAD");', [
//    "position" => \yii\web\View::POS_LOAD
//]);
// Yii::info("使能测试", "login");
// var_dump(Yii::$app->log->targets["login"]->messages = ["test", "info", "login"]);die;
// die;

echo Markdown::widget(["content" => implode("\n", $html)]);

